using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class InGameTutorialStep : EventCommander
{
	public float waitAfterStart;

	public string[] startStepMessage = new string[0];

	public string[] endStepMessage = new string[0];

	public float waitAfterPrintText;

	public GameObject UIroot;

	[Space(10f)]
	public bool reloadTutorOnStart;

	public bool dontBlockIfNoMsg;

	public bool skipOnLoaded;

	public bool skipOnTap = true;

	public bool saveStep = true;

	public bool blockScreen = true;

	public int stepPriority;

	[Space(10f)]
	public List<NextSteps> nextSteps;

	public IngameTutorialType objectsType;

	[Space(10f)]
	private bool started;

	private bool ended;

	private bool printing;

	private List<EventCommander> commanders = new List<EventCommander>();

	private float cWateTime;

	private InGameTutorBlockPanel panel;

	private InGameTutorial[] arrTutorial;

	private List<InGameTutorialStep> otherSteps = new List<InGameTutorialStep>();

	private float wateTime;

	private bool lastPaused;

	private string lastMsg = string.Empty;

	private IEnumerator endStep;

	public virtual void StartTutorialStep()
	{
		started = true;
		GameController.changeLevel += OnLevelWasUnloaded;
		foreach (EventCommander commander in commanders)
		{
			if (commander == null || objectsType != 0)
			{
				continue;
			}
			InGametutorialStepSettings[] values = ((InGameTutorialObject)commander).values;
			for (int i = 0; i < values.Length; i++)
			{
				InGametutorialStepSettings element = values[i];
				nextSteps.ForEach(delegate(NextSteps x)
				{
					if (x.endEventArg.Equals(element.value))
					{
						((InGameTutorialObject)commander).OnEnd();
					}
				});
			}
		}
		StopCoroutine(StartStep());
		StartCoroutine(StartStep());
	}

	public bool ChkOtherStepBlock()
	{
		if (UIroot == null)
		{
			return false;
		}
		if (panel == null)
		{
			panel = UIroot.GetComponentInChildren<InGameTutorBlockPanel>();
		}
		if (arrTutorial == null)
		{
			arrTutorial = Object.FindObjectsOfType<InGameTutorial>();
		}
		otherSteps.Clear();
		for (int i = 0; i < arrTutorial.Length; i++)
		{
			if (arrTutorial[i].cStep != null)
			{
				otherSteps.Add(arrTutorial[i].cStep);
			}
		}
		for (int j = 0; j < otherSteps.Count; j++)
		{
			if (otherSteps[j] != this && otherSteps[j].UIroot != null && otherSteps[j].stepPriority > stepPriority)
			{
				if (otherSteps[j].dontBlockIfNoMsg && !otherSteps[j].ended && otherSteps[j].startStepMessage.Length <= 0)
				{
					return false;
				}
				return true;
			}
		}
		return false;
	}

	protected virtual IEnumerator StartStep()
	{
		if (UIroot == null)
		{
			yield break;
		}
		int startedObjects = 0;
		yield return StartCoroutine(BCWUtils.WaitForRealSeconds(waitAfterStart));
		switch (objectsType)
		{
		case IngameTutorialType.EventCommander:
			commanders.Clear();
			commanders.AddRange(Object.FindObjectsOfType<EventCommander>());
			break;
		case IngameTutorialType.InGametutorialObject:
		{
			InGameTutorialObject[] tmp = Object.FindObjectsOfType<InGameTutorialObject>();
			InGameTutorialObject[] tmp2 = UIroot.GetComponentsInChildren<InGameTutorialObject>(true);
			commanders.Clear();
			commanders.AddRange(tmp);
			for (int j = 0; j < tmp2.Length; j++)
			{
				commanders.RemoveAll((EventCommander x) => x == tmp2[j]);
			}
			commanders.AddRange(tmp2);
			for (int k = 0; k < commanders.Count; k++)
			{
				commanders[k].AddEventListener(this, "ShowThis", delegate(Object sender, object[] args)
				{
					RiseEvent(this, "ShowElement", ((InGameTutorialObject)sender).gameObject, (bool)args[0]);
				});
				if (!(commanders[k] is InGameTutorialObject))
				{
					continue;
				}
				for (int m = 0; m < nextSteps.Count; m++)
				{
					if (((InGameTutorialObject)commanders[k]).OnStepStart(nextSteps[m].endEventArg))
					{
						startedObjects++;
					}
				}
			}
			break;
		}
		case IngameTutorialType.InGameTutorial:
		{
			InGameTutorial[] tmp3 = Object.FindObjectsOfType<InGameTutorial>();
			commanders.Clear();
			commanders.AddRange(tmp3);
			for (int l = 0; l < tmp3.Length; l++)
			{
				commanders[l] = tmp3[l];
			}
			break;
		}
		case IngameTutorialType.NONE:
			if (endStep != null)
			{
				StopCoroutine(endStep);
			}
			endStep = EndStep((nextSteps.Count <= 0) ? string.Empty : nextSteps[0].nextStep);
			StartCoroutine(endStep);
			yield break;
		}
		foreach (EventCommander commander in commanders)
		{
			if (commander == null)
			{
				continue;
			}
			commander.Init();
			commander.AddEventListener(this, "Used", delegate(Object sender, object[] args)
			{
				string value = (string)args[0];
				NextSteps item = nextSteps.Find((NextSteps x) => x.endEventArg == value);
				if (nextSteps.Contains(item))
				{
					endStep = EndStep(item.nextStep);
					StartCoroutine(endStep);
				}
			});
		}
		RiseEvent(this, "Started", base.name);
		while (ChkOtherStepBlock())
		{
			yield return StartCoroutine(BCWUtils.WaitForRealSeconds(0.5f));
		}
		if (startStepMessage.Length > 0)
		{
			do
			{
				yield return null;
				wateTime += Time.unscaledDeltaTime;
			}
			while (!(wateTime >= cWateTime));
		}
		if (!started)
		{
			yield break;
		}
		if (startStepMessage.Length == 0)
		{
			RiseEvent(this, "PrintText", string.Empty);
		}
		for (int i = 0; i < startStepMessage.Length; i++)
		{
			while (ChkOtherStepBlock())
			{
				yield return StartCoroutine(BCWUtils.WaitForRealSeconds(0.5f));
			}
			PauseStep(false);
			cWateTime = waitAfterPrintText;
			lastMsg = startStepMessage[i];
			RiseEvent(this, "PrintText", startStepMessage[i]);
			printing = true;
			wateTime = 0f;
			do
			{
				yield return null;
				wateTime += Time.deltaTime;
			}
			while (!(wateTime >= cWateTime));
		}
		if (blockScreen && startedObjects == 0)
		{
			if (endStep != null)
			{
				StopCoroutine(endStep);
			}
			endStep = EndStep(nextSteps[0].nextStep);
			panel.EnableBlock(false);
			StartCoroutine(endStep);
		}
		yield return null;
	}

	protected virtual void PauseStep(bool val)
	{
		if (lastPaused == val)
		{
			return;
		}
		lastPaused = val;
		if (!val)
		{
			RiseEvent(this, "PrintText", lastMsg);
		}
		foreach (EventCommander commander in commanders)
		{
			InGameTutorialObject inGameTutorialObject = commander as InGameTutorialObject;
			if (inGameTutorialObject != null)
			{
				inGameTutorialObject.OnStepPause(val);
			}
		}
	}

	protected virtual IEnumerator EndStep(string nextStepName)
	{
		foreach (EventCommander commander in commanders)
		{
			commander.RemoveAllEventListeners(this);
		}
		if (!started)
		{
			yield break;
		}
		started = false;
		ended = true;
		while (ChkOtherStepBlock())
		{
			yield return StartCoroutine(BCWUtils.WaitForRealSeconds(0.5f));
		}
		if (endStepMessage.Length == 0)
		{
			RiseEvent(this, "PrintText", string.Empty);
		}
		for (int i = 0; i < endStepMessage.Length; i++)
		{
			printing = true;
			cWateTime = waitAfterPrintText;
			lastMsg = endStepMessage[i];
			RiseEvent(this, "PrintText", endStepMessage[i]);
			wateTime = 0f;
			do
			{
				yield return null;
				wateTime += Time.unscaledDeltaTime;
			}
			while (!(wateTime >= cWateTime));
			while (ChkOtherStepBlock())
			{
				yield return StartCoroutine(BCWUtils.WaitForRealSeconds(0.5f));
			}
		}
		printing = false;
		Ended(nextStepName);
	}

	protected virtual void Ended(string nextStepName)
	{
		GameController.changeLevel -= OnLevelWasUnloaded;
		ended = true;
		started = false;
		RiseEvent(this, "PrintText", string.Empty);
		foreach (EventCommander commander in commanders)
		{
			if (commander == null || objectsType != 0)
			{
				continue;
			}
			InGametutorialStepSettings[] values = ((InGameTutorialObject)commander).values;
			for (int i = 0; i < values.Length; i++)
			{
				InGametutorialStepSettings element = values[i];
				nextSteps.ForEach(delegate(NextSteps x)
				{
					if (x.endEventArg.Equals(element.value))
					{
						((InGameTutorialObject)commander).OnEnd();
					}
				});
			}
		}
		RiseEvent(this, "StartNextStep", nextStepName);
	}

	private void OnLevelWasUnloaded()
	{
		if (ended || (skipOnLoaded && started))
		{
			Ended((nextSteps.Count <= 0) ? string.Empty : nextSteps[0].nextStep);
		}
	}

	private void OnDestroy()
	{
		GameController.changeLevel -= OnLevelWasUnloaded;
	}

	public void Update()
	{
		PauseStep(ChkOtherStepBlock());
		if (!skipOnTap)
		{
			return;
		}
		Touch[] touches = Input.touches;
		for (int i = 0; i < touches.Length; i++)
		{
			Touch touch = touches[i];
			if (touch.phase == TouchPhase.Began && touch.position.y < (float)(Screen.height / 2))
			{
				wateTime = cWateTime;
			}
		}
		if (Input.GetMouseButtonDown(0) && Input.mousePosition.y < (float)(Screen.height / 2))
		{
			wateTime = cWateTime;
		}
	}

	public override void Init()
	{
		base.Init();
		InitEvents(new string[5] { "Started", "Ended", "PrintText", "StartNextStep", "ShowElement" });
	}
}
